package com.fly.hello.resful.json;

import java.io.IOException;
import java.io.StringReader;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;

/**
 * Json字符串格式化
 */
@Slf4j
public class JsonPrettyFormat
{
    // thread-safe
    ObjectMapper mapper = new ObjectMapper();
    
    private String jsonString =
        "{\"_index\":\"book_shop\",\"_type\":\"it_book\",\"_id\":\"1\",\"_score\":1.0, \"_source\":{\"name\": \"Java编程思想（第4版）\",\"author\": \"[美] Bruce Eckel\",\"category\": \"编程语言\", \"price\": 109.0,\"publisher\": \"机械工业出版社\",\"date\": \"2007-06-01\",\"tags\": [ \"Java\", \"编程语言\" ]}}";
    
    @Test
    public void jacksonTest()
        throws JsonMappingException, JsonProcessingException
    {
        Object obj = mapper.readValue(jsonString, Object.class);
        String pretty = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        log.info("{} ", pretty);
        
        JsonNode jsonNode = mapper.readTree(jsonString);
        pretty = jsonNode.toPrettyString();
        log.info("{} ", pretty);
    }
    
    @Test
    public void printTest()
        throws IOException
    {
        JsonNode jsonNode = mapper.readTree(jsonString);
        String pretty = jsonNode.toPrettyString();
        log.info("{} ", pretty);
        
        String name = IOUtils.readLines(new StringReader(pretty))
            .stream()
            .filter(line -> line.contains("\"name\""))
            .map(line -> StringUtils.deleteWhitespace(line)) //
            .map(line -> StringUtils.substringBetween(line, ":\"", "\""))
            .collect(Collectors.joining());
        log.info("name => {} ", name);
        
        // findFirst 不存在,直接get会报错
        Optional<String> optional = IOUtils.readLines(new StringReader(pretty))
            .stream()
            .filter(line -> line.contains("\"name\""))
            .map(line -> StringUtils.deleteWhitespace(line)) //
            .map(line -> StringUtils.substringBetween(line, ":\"", "\""))
            .findFirst();
        if (optional.isPresent())
        {
            log.info("name => {} ", optional.get());
        }
    }
}
